﻿#include "ConcurrentAlloc.h"

void BenchmarkMalloc(size_t ntimes, size_t nworks, size_t rounds)
{
	// 创建线程
	std::vector<std::thread> vthread(nworks);
	// 使用原子变量保证原子性
	std::atomic<size_t> malloc_costtime = 0;
	std::atomic<size_t> free_costtime = 0;

	for (size_t k = 0; k < nworks; ++k)
	{
		vthread[k] = std::thread([&, k]() {
			std::vector<void*> v;
			v.reserve(ntimes);

			for (size_t j = 0; j < rounds; ++j)
			{
				size_t begin1 = clock();
				for (size_t i = 0; i < ntimes; i++)
				{
					v.push_back(malloc((16 + i) % 8192 + 1));
				}
				size_t end1 = clock();

				size_t begin2 = clock();
				for (size_t i = 0; i < ntimes; i++)
				{
					free(v[i]);
				}
				size_t end2 = clock();
				v.clear();

				malloc_costtime += (end1 - begin1);
				free_costtime += (end2 - begin2);
			}
			});
	}

	// 线程等待
	for (auto& t : vthread)
	{
		t.join();
	}

	printf("%zu个线程并发执行%zu轮次，每轮次malloc %zu次: 花费：%zu ms\n", nworks, rounds, ntimes, static_cast<size_t>(malloc_costtime));

	printf("%zu个线程并发执行%zu轮次，每轮次free %zu次: 花费：%zu ms\n", nworks, rounds, ntimes, static_cast<size_t>(free_costtime));

	printf("%zu个线程并发malloc & free %zu次，总计花费：%zu ms\n", nworks, nworks * rounds * ntimes, static_cast<size_t>(malloc_costtime + free_costtime));
}


// 单轮次申请释放次数 线程数 轮次
void BenchmarkConcurrentMalloc(size_t ntimes, size_t nworks, size_t rounds)
{
	std::vector<std::thread> vthread(nworks);
	std::atomic<size_t> malloc_costtime = 0;
	std::atomic<size_t> free_costtime = 0;

	for (size_t k = 0; k < nworks; ++k)
	{
		vthread[k] = std::thread([&]() {
			std::vector<void*> v;
			v.reserve(ntimes);

			for (size_t j = 0; j < rounds; ++j)
			{
				int begin1 = clock();
				for (size_t i = 0; i < ntimes; i++)
				{
					v.push_back(ConcurrentAlloc((16 + i) % 8192 + 1));
				}
				int end1 = clock();

				int begin2 = clock();
				for (size_t i = 0; i < ntimes; i++)
				{
					ConcurrentFree(v[i]);
				}
				int end2 = clock();
				v.clear();

				malloc_costtime += (end1 - begin1);
				free_costtime += (end2 - begin2);
			}
			});
	}

	for (auto& t : vthread)
	{
		t.join();
	}

	printf("%zu个线程并发执行%zu轮次，每轮次ConcurrentAlloc %zu次: 花费：%zu ms\n",
		nworks, rounds, ntimes, static_cast<size_t>(malloc_costtime));

	printf("%zu个线程并发执行%zu轮次，每轮次ConcurrentDealloc %zu次: 花费：%zu ms\n",
		nworks, rounds, ntimes, static_cast<size_t>(free_costtime));

	printf("%zu个线程并发ConcurrentAlloc & ConcurrentDealloc %zu次，总计花费：%zu ms\n",
		nworks, nworks * rounds * ntimes, static_cast<size_t>(malloc_costtime + free_costtime));
}

// 性能测试：对照malloc、free
int main()
{
	// 多轮测试
	for (int i = 0; i < 10; ++i)
	{
		size_t n = 10000;
		std::cout << "==========================================================" << std::endl;
		BenchmarkConcurrentMalloc(n, 4, 10);
		std::cout << std::endl << std::endl;

		BenchmarkMalloc(n, 4, 10);
		std::cout << "==========================================================" << std::endl;
	}
	return 0;
}